<?php

namespace app\models;

use app\components\BaseActiveRecord;
use Yii;
use yii\caching\TagDependency;
use yii\db\Exception;

/**
 * This is the model class for table "{{%meta}}".
 *
 * @property int $id
 * @property int $parent_id
 * @property int $type
 * @property string $name
 * @property string $description
 * @property string $slug
 * @property int $sort
 * @property int $count
 * @property int $is_hide
 */
class Meta extends BaseActiveRecord {

    const TYPE_TAG = 1;
    const TYPE_AUTHOR = 2;
    const TYPE_BANNER = 3;
    const TYPE_CATEGORY = 4;
    const TYPE_LINK = 5;

    const CACHE_BANNER_TAG = 'banners';
    const CACHE_CATEGORY_TAG = 'category';
    const CACHE_LINK_TAG = 'link';

    public static $typeLabels = [];

    public function init() {
        parent::init();
        self::$typeLabels = [
            self::TYPE_TAG => Yii::t('app', 'Tag'),
            self::TYPE_AUTHOR => Yii::t('app', 'Author')
        ];
    }


    /**
     * {@inheritdoc}
     */
    public static function tableName() {
        return '{{%meta}}';
    }

    /**
     * {@inheritdoc}
     */
    public function rules() {
        return [
            [['name'], 'required'],
            [['parent_id', 'type', 'sort', 'count', 'is_hide'], 'integer'],
            [['name'], 'string', 'max' => 160],
            [['description'], 'string', 'max' => 200],
            [['slug'], 'string', 'max' => 100],
//            [['slug'], 'unique', 'skipOnEmpty' => TRUE],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels() {
        return [
            'id' => Yii::t('app', 'ID'),
            'parent_id' => Yii::t('app', 'Parent ID'),
            'type' => Yii::t('app', 'Type'),
            'name' => Yii::t('app', 'Name'),
            'description' => Yii::t('app', 'Description'),
            'slug' => Yii::t('app', 'Slug'),
            'sort' => Yii::t('app', 'Sort'),
            'count' => Yii::t('app', 'Count'),
            'is_hide' => Yii::t('app', 'Is Hide'),
        ];
    }

    public function isBanner() {
        return intval($this->type) === intval(self::TYPE_BANNER);
    }

    public function isCategory() {
        return intval($this->type) === intval(self::TYPE_CATEGORY);
    }

    public function isAuthor() {
        return intval($this->type) === intval(self::TYPE_AUTHOR);
    }


    public function getTag() {
        return $this->hasMany(Relationship::class, ['meta_id' => 'id']);
    }

    public static function getMetas($owner_id) {
        $models = Relationship::find()->with(['meta'])->where(['owner_id' => $owner_id])->asArray()->all();
        $data = [];
        foreach ($models as $i => $model) {
            if (empty($model['meta'])) {
                continue;
            }
            $data[$model['meta']['id']] = $model['meta']['name'];
        }
        return $data;
    }

    public function getRelations() {
        return $this->hasMany(Relationship::class, ['meta_id' => 'id']);
    }

    protected static function editSaveMeta($owner_id, $data) {
        $oldMetas = static::getMetas($owner_id);
        $meta_ids = array_keys($oldMetas);
        $oldMetas = array_values($oldMetas);

        $tagName = implode(',', $oldMetas);
        if ($tagName === trim($data)) {
            return FALSE;
        }

        Relationship::deleteAll(['owner_id' => $owner_id]);
        Meta::updateAllCounters(['count' => -1], ['id' => $meta_ids]);

        return TRUE;
    }

    /**
     * @param $data
     * @param $owner_id
     * @param int $type
     * @throws Exception
     */
    public static function saveMetaRelation($data, $owner_id, $type = self::TYPE_TAG) {
        if (!self::editSaveMeta($owner_id, $data)) {
            return;
        }

        $data = array_unique(explode(',', $data));
        $relation_data = [];
        foreach ($data as $v) {
            $v = trim($v);
            if (empty($v)) {
                continue;
            }
            $model = self::find()->where(['name' => $v, 'type' => $type])->one();
            if (!$model) {
                $model = new static();
                $model->name = $v;
                $model->type = $type;
                $model->slug = $v;
            }
            $model->count = $model->count + 1;
            $model->save();
            $relation_data[] = [$owner_id, $model->id, $model->type];
        }
        if ($relation_data) {
            Yii::$app->db->createCommand()->batchInsert(Relationship::tableName(), ['owner_id', 'meta_id', 'meta_type'], $relation_data)->execute();
        }
    }


    /**
     * @param $data
     * @param int $type
     * @return int|mixed|null
     * @throws Exception
     */
    public static function saveMeta($data, $type = self::TYPE_TAG) {
        if (empty($data['slug'])) {
            $data['slug'] = $data['name'];
        }
        $model = self::find()->where(['name' => $data['name'], 'type' => $type])->one();
        if (!$model) {
            $model = new static();
        }
        $model->setAttributes($data);
        $model->count = $model->count + 1;
        $model->type = $type;
        $model->save();
        return $model->id;
    }

    public function refreshCache() {
        if ($this->isBanner()) {
            TagDependency::invalidate(Yii::$app->cache, self::CACHE_BANNER_TAG);
        }
        parent::refreshCache();
    }

    public static function getBanners($limit = 6) {
        $dependency = new TagDependency(['tags' => Meta::CACHE_BANNER_TAG]);
        return self::find()->cache(0, $dependency)->where(['type' => Meta::TYPE_BANNER, 'is_hide' => Meta::NO])->asArray()->limit($limit)->orderBy('id desc')->all();
    }

    public static function getLinks() {
        $dependency = new TagDependency(['tags' => Meta::CACHE_LINK_TAG]);
        return self::find()->cache(0, $dependency)->where(['type' => Meta::TYPE_LINK, 'is_hide' => Meta::NO])->asArray()->orderBy('id desc')->all();
    }
}
